﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Company.Project.Domain.Base;
using Company.Project.Domain.MainModule.Interface;
using Company.Project.Domain.Model;
using Company.Utility;

namespace Company.Project.Domain.MainModule
{
    public class Project_SYS_RoleDomainServices : IProject_SYS_RoleDomainServices
    {
        private readonly IProject_SYS_RoleRepository _repository;
        private readonly IProject_SYS_RoleActionRepository _roleActionRepository;
        private readonly IProject_SYS_ModuleActionRepository _moduleActionRepository;
        private readonly IProject_Manager_BaseInfoRepository _baseInfoRepository;

        public Project_SYS_RoleDomainServices(IProject_SYS_RoleRepository repository,
            IProject_SYS_RoleActionRepository roleActionRepository,
            IProject_SYS_ModuleActionRepository moduleActionRepository,
            IProject_Manager_BaseInfoRepository baseInfoRepository)
        {
            this._repository = repository;
            _roleActionRepository = roleActionRepository;
            _moduleActionRepository = moduleActionRepository;
            _baseInfoRepository = baseInfoRepository;
        }
        public async Task AddRole(Project_SYS_Role model, List<Project_SYS_ModuleAction> moduleAction)
        {
            if (string.IsNullOrEmpty(model.RoleName))
            {
                throw new CustomException("请输入角色名称!");
            }
            if (model.OrderID < 0)
            {
                model.OrderID = 0;
            }
            if (model.ID == Guid.Empty)
            {
                //Add
                model.ID = Guid.NewGuid();
                if (moduleAction != null && moduleAction.Any())
                {
                    var oldIds = moduleAction.Select(y => y.ID);
                    var myold = await
                        _moduleActionRepository.GetManyAsync(
                            new DirectSpecification<Project_SYS_ModuleAction>(
                                x => oldIds.Contains(x.ID) && !x.IsDeleted));
                    var old = myold.Select(x => new {x.ModuleID, x.Weight})
                        .ToList();
                    if (old.Count() != moduleAction.Count)
                    {
                        throw new CustomException("部分模块状态被更改,请刷新页面重试!");
                    }
                    model.RoleActions = new List<Project_SYS_RoleAction>();
                    old.GroupBy(x => x.ModuleID).ToList().ForEach(x =>
                    {
                        model.RoleActions.ToList().Add(new Project_SYS_RoleAction()
                        {
                            ID = Guid.NewGuid(),
                            ModuleID = x.Key,
                            RoleID = model.ID,
                            Weight = x.Sum(y => y.Weight)
                        });
                    });
                }
                _repository.Add(model);
            }
            else
            {
                //Edit
                var item =await _repository.GetRoleAndAction(model.ID);
                if (item == null || item.IsDeleted)
                {
                    throw new CustomException("没有查询到该角色,请重试!");
                }
                item.Memo = model.Memo;
                item.OrderID = model.OrderID;
                item.RoleName = model.RoleName;
                _repository.Update(item, x => x.Memo, x => x.OrderID, x => x.RoleName);
                if (moduleAction != null && moduleAction.Any())
                {
                    var oldIds = moduleAction.Select(y => y.ID);
                    var oldRoleActId = item.RoleActions.Select(x => new {x.ModuleID, x.ID});
                    var myold =await 
                        _moduleActionRepository.GetManyAsync(
                            new DirectSpecification<Project_SYS_ModuleAction>(
                                x => oldIds.Contains(x.ID) && !x.IsDeleted));
                    var old = myold.Select(x => new {x.ModuleID, x.Weight})
                        .ToList();
                    if (old.Count() != moduleAction.Count)
                    {
                        throw new CustomException("部分模块状态被更改,请刷新页面重试!");
                    }
                    var roleActions = new List<Project_SYS_RoleAction>();
                    old.GroupBy(x => x.ModuleID).ToList().ForEach(x =>
                    {
                        var oldroleaction = item.RoleActions.Where(y => y.ModuleID == x.Key);
                        oldroleaction.ToList().ForEach(y =>
                        {
                            y.Weight = x.Sum(z => z.Weight);
                            _roleActionRepository.Update(y, z => z.Weight);
                        });
                        if (!item.RoleActions.ToList().Exists(y => y.ModuleID == x.Key))
                        {
                            roleActions.Add(new Project_SYS_RoleAction()
                            {
                                ID = Guid.NewGuid(),
                                ModuleID = x.Key,
                                RoleID = model.ID,
                                Weight = x.Sum(y => y.Weight)
                            });
                        }
                    });
                    if (roleActions.Any())
                    {
                        _roleActionRepository.AddBatch(roleActions);
                    }
                    var removeoldid =
                        oldRoleActId.Where(x => !old.Select(y => y.ModuleID).Contains(x.ModuleID)).Select(x => x.ID);
                    if (removeoldid != null && removeoldid.Any())
                    {
                        _roleActionRepository.Remove(
                            new DirectSpecification<Project_SYS_RoleAction>(x => removeoldid.Contains(x.ID)));
                    }
                }
                else
                {
                    var removeid = item.RoleActions.Select(x => x.ID);
                    if (removeid != null && removeid.Any())
                    {
                        _roleActionRepository.Remove(
                            new DirectSpecification<Project_SYS_RoleAction>(x => removeid.Contains(x.ID)));
                    }
                }
            }
        }

        public async Task<IEnumerable<string>> DelRole(IEnumerable<Guid> ids)
        {
            if (ids.Any())
            {
                if ((await _baseInfoRepository.ExistsRoleByRoleId(ids)))
                {
                    throw new CustomException("当前角色下有管理账号存在,请先删除账号再删除角色!");
                }
                else
                {
                    _repository.LogicDelete(
                        new DirectSpecification<Project_SYS_Role>(x => ids.Contains(x.ID)));
                    return (await
                        _repository.GetManyAsync(new DirectSpecification<Project_SYS_Role>(x => ids.Contains(x.ID)))
                        ).Select(x => x.RoleName);
                }
            }
            else
            {
                throw new CustomException("请至少选择一个角色!");
            }
        }
    }
}
